package com.advaita.gui2;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.border.EtchedBorder;

import com.advaita.license.Selection;

public class ItemSelectPanel {

	/*
	 * ItemsPanel[i] is the JFrame for the ith item. i=0 means Organism, and so
	 * on
	 */
	/* Items[0] is the button for Organism, and so on */
	/* SelectionList[0] is the list of "Selection"s for Organism, and so on */
	/* SourceList[0] is the source JList for Organism, and so on */
	/* DestList[0] is the destination JList for Organism, and so on */
	/*
	 * Similarly, SourceModel[0] and DestModel[0] are the source and destination
	 * DefaultListModels for Organism, and so on
	 */
	/*
	 * AddButton[0] is the sourcelist->destlist button in the JFrame
	 * ItemsPanel[0], and so on; similarly RemoveButton[0]
	 */
	/*
	 * SelectionOptions[0][] is an array of upto 15 strings of the Organisms
	 * that will be displayed, and so on
	 */

	private JFrame MainFrame;
	private JPanel MainPanel;

	private JPanel[] ItemsPanel = new JPanel[6];
	private JButton[] Items = new JButton[6];
	private List<Selection>[] SelectionList = new ArrayList[6]; // SelectionList
																// = new
																// ArrayList[5];
	private JList[] SourceList = new JList[6];
	private JList[] DestList = new JList[6];
	private DefaultListModel[] SourceModel = new DefaultListModel[6];
	private DefaultListModel[] DestModel = new DefaultListModel[6];
	private JButton[] AddButton = new JButton[6];
	private JButton[] RemoveButton = new JButton[6];
	private JButton[] SaveExitButton = new JButton[6];

	private String[][] SelectionOptions = new String[6][15];

	/**
	 * Launch the application.
	 */

	public static void main(String[] args) {
		ItemSelectPanel.setLookAndFeel();

		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					ItemSelectPanel window = new ItemSelectPanel();
					window.MainFrame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */

	public ItemSelectPanel() {
		ItemSelectPanel.setLookAndFeel();

		// For each i, initialize the list of selections for that Items-category
		// i.

		for (int i = 0; i < 6; i++) {
			SelectionList[i] = new ArrayList<Selection>();

		}

		initialize_SelectionOptions(); // Fills the Collection of Items array
										// for each Category

		FormatFrame(); // Creates the main frame etc
	}

	/*
	 * This is the method to call to get back the SelectionList Array of 5
	 * entries, each of which is a List of Selections. Each Selection contains
	 * the string and boolean. The caller can access as follows, for example:
	 * for(Selection selection: SelectionList[i]) {selection.getSelection();
	 * selection.getIsEnabled();...}
	 */

	public List<Selection>[] returnSelections() {

		return SelectionList;

	}

	/* This fills up our SelectionOption arrays */

	private void initialize_SelectionOptions() {
		String[] Organism = { "Homo sapien", "Mus muculus", "Rattus novegicus",
				"Arabidopsis thaliana (Thale cress)",
				"Drosophilla melanogaster (Fruit Fly)",
				"Canis lupus familiaris (Dog)", "Danio rerio (Zebrafish)",
				"Caenorhabiditus elegans (Nematode)",
				"Gallus gallus (chicken)", "Bos taurus (Cow/Bovine)",
				"Sus scrofa domesticus (Pig)" };

		String[] MicroArray = { "Affymatrix", "Applied Biosystems",
				"HitachiSoft", "Illumina", "Invitrogen", "Miltenyl Biotech",
				"NimbleGen", "Agilent Technologies", "Ocimum Biosolutions",
				"Operon", "Phalanx Biotech",
				"Rosetta Inpharmatics/Merck Parmaceuticals" };

		String[] Geneid = { "Entrez", "Gene Symbol", "GeneBank Accession",
				"GeneBank Gis", "Ensemble", "Probe ID" };

		String[] PathwayDB = { "Reactome", "KEGG" };

		String[] Analysis = { "DE Genes Impact Analysis",
				"DE Genes Coherent Chains of Perturbation",
				"All Genese Impact Analysis", "All Genes with GSA & PADOG" };
		String[] EXIT = {};

		SelectionOptions[0] = Organism;
		SelectionOptions[1] = MicroArray;
		SelectionOptions[2] = Geneid;
		SelectionOptions[3] = PathwayDB;
		SelectionOptions[4] = Analysis;
		SelectionOptions[5] = EXIT;

	}

	/*
	 * FormatFrame() displays the main frame with the five items to choose from.
	 * The user will click on the item to have the corresponding JFrame
	 * ItemsPanel[i] displayed and then can choose. The method also initializes
	 * these frames and creates the List of Selections in the background; but
	 * they will be displayed only when the user clicks. JFrame
	 */

	private void FormatFrame() {

		MainFrame = new JFrame();

		MainFrame.setSize(800, 600);
		MainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Items[0] = new JButton("Organism");
		Items[1] = new JButton("MicroArray");
		Items[2] = new JButton("Geneid");
		Items[3] = new JButton("PathwayDB");
		Items[4] = new JButton("Analysis");
		Items[5] = new JButton("EXIT");

		MainPanel = new JPanel();
		JLabel chooseLabel = new JLabel(
				"Choose an item and make choice for a subcategory.");
		MainPanel.add(chooseLabel);
		ButtonGroup group = new ButtonGroup();
		for (JButton team : Items) {
			group.add(team);
			MainPanel.add(team);

		}

		MainFrame.setVisible(true);
		Items[0].addActionListener(new AddListener_team(0));
		Items[1].addActionListener(new AddListener_team(1));
		Items[2].addActionListener(new AddListener_team(2));
		Items[3].addActionListener(new AddListener_team(3));
		Items[4].addActionListener(new AddListener_team(4));
		Items[5].addActionListener(new AddListener_team(5));

		// Initialize the frames for each of the Items; but don't make them
		// visible

		for (int i = 0; i < 6; i++) {
			initialize(i);
			CreateSelections(i);
			SetUpSelections(i);
		}
	}

	/*
	 * If the user clicks "Organism" button, then if it is not visible, that
	 * frame is made visible. If already visible, it is brought to the Front of
	 * other frames.
	 */

	private class AddListener_team implements ActionListener {
		private int index;

		public AddListener_team(int i) {
			index = i;
		}

		public void actionPerformed(ActionEvent e) {
			if (index == 5) {
				MainFrame.setVisible(false);
			//	MainFrame.dispose();
			} else {
				for (int i = 0; i < 5; i++) {
					if (i == index) {
						ItemsPanel[i].setVisible(true);
					} else {
						ItemsPanel[i].setVisible(false);
					}
				}

			}
		}
	}

	/*
	 * Fill up Selections with the strings in SelectionOptions, set booleans to
	 * false, and add to SelectionList
	 */

	private void CreateSelections(int index) {

		int size;

		size = Array.getLength(SelectionOptions[index]);
		for (int i = 0; i < size; i++) {
			Selection selection = new Selection();
			selection.setSelection(SelectionOptions[index][i]);
			selection.setIsEnabled(false);
			SelectionList[index].add(selection);
		}
	}

	/*
	 * Put the selection strings into the SourceModels, so that they are
	 * displayed in the SourceList
	 */

	public void SetUpSelections(int index) {

		for (Selection selection : SelectionList[index]) {

			if (selection.getIsEnabled()) {
				DestModel[index].addElement(selection.getSelection());
			} else {
				SourceModel[index].addElement(selection.getSelection());
			}
		}
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize(int i) {

		SourceModel[i] = new DefaultListModel();
		DestModel[i] = new DefaultListModel();
		ItemsPanel[i] = new JPanel();
		ItemsPanel[i].setBounds(50, 120, 800, 500);

		ItemsPanel[i].setLayout(null);
		// ItemsPanel[i].setLayout(new GridLayout());

		SourceList[i] = new JList(SourceModel[i]);
		SourceList[i].setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		SourceList[i].setBounds(50, 50, 221, 262);
		ItemsPanel[i].add(SourceList[i]);

		DestList[i] = new JList(DestModel[i]);
		DestList[i].setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		DestList[i].setBounds(391, 50, 221, 262);
		ItemsPanel[i].add(DestList[i]);

		AddButton[i] = new JButton(">>");
		AddButton[i].setBounds(291, 91, 89, 23);
		ItemsPanel[i].add(AddButton[i]);

		RemoveButton[i] = new JButton("<<");
		RemoveButton[i].setBounds(291, 154, 89, 23);
		ItemsPanel[i].add(RemoveButton[i]);

		SaveExitButton[i] = new JButton("Save/Exit");
		SaveExitButton[i].setBounds(291, 217, 89, 23);
		ItemsPanel[i].add(SaveExitButton[i]);

		AddButton[i].addActionListener(new AddListener(i));
		RemoveButton[i].addActionListener(new RemoveListener(i));
		SaveExitButton[i].addActionListener(new SaveExitListener(i));

		MainFrame.getContentPane().add(MainPanel, BorderLayout.CENTER);
		ItemsPanel[i].setVisible(false);
		MainFrame.getContentPane().add(ItemsPanel[i], BorderLayout.SOUTH);
	}

	/*
	 * Make invisible the JFrame ItemsPanel[i] if its SaveExit button is pressed
	 * by user
	 */

	private class SaveExitListener implements ActionListener {

		private int index;

		public SaveExitListener(int i) {
			index = i;
		}

		public void actionPerformed(ActionEvent e) {

			ItemsPanel[index].setVisible(false);
		}
	}

	/*
	 * Add selected items in SourceList to DestList; remove from SourceList
	 */

	private class AddListener implements ActionListener {

		private int index;

		public AddListener(int i) {
			index = i;
		}

		public void actionPerformed(ActionEvent e) {
			List<String> selected = SourceList[index].getSelectedValuesList();

			String selectedItems;

			for (int i = 0; i < selected.size(); i++) {
				selectedItems = selected.get(i);
				DestModel[index].addElement(selectedItems);
				SourceModel[index].removeElement(selectedItems);

				for (Selection selection : SelectionList[index]) {
					if (selectedItems == selection.getSelection()) {
						selection.setIsEnabled(true);
					}
				}
			}
		}
	}

	/*
	 * Remove selected items in DestList and put into sourceList
	 */

	private class RemoveListener implements ActionListener {

		private int index;

		public RemoveListener(int i) {
			index = i;
		}

		public void actionPerformed(ActionEvent e) {
			List<String> selected = DestList[index].getSelectedValuesList();

			String selectedItems;

			for (int i = 0; i < selected.size(); i++) {
				selectedItems = selected.get(i);
				SourceModel[index].addElement(selectedItems);
				DestModel[index].removeElement(selectedItems);

				for (Selection selection : SelectionList[index]) {
					if (selectedItems == selection.getSelection()) {
						selection.setIsEnabled(false);
					}
				}

			}

		}
	}

	public static void setLookAndFeel() {
		try {
			UIManager
					.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
		} catch (Exception exc) {
			System.out.println(exc.getMessage());
		}
	}
}
